package com.zjy.business.system.dao;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.github.pagehelper.PageInfo;
import com.zjy.business.system.domain.entity.SysConfig;
import com.zjy.business.system.domain.manager.query.ManagerListPageSysConfigQuery;
import com.zjy.business.system.mapper.SysConfigMapper;
import com.zjy.common.constant.SysConfigEnum;
import com.zjy.config.RedisServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

/**
 * @author yxb
 * create_time: 2024-10-24 10:23
 * description: 
 */
@Slf4j
@Service
public class SysConfigDao extends RedisServiceImpl<SysConfigMapper, SysConfig> {
    public PageInfo<SysConfig> listPageSysConfig(ManagerListPageSysConfigQuery query) {
        return this.baseMapper.listPageSysConfig(query);
    }

    /**
     * 根据系统配置枚举查询缓存中的系统配置内容
     * 如果缓存中没有找到相关配置，则返回系统配置枚举中的默认内容
     *
     * @param sysConfigEnum 系统配置枚举，用于标识需要查询的配置类型
     * @return 缓存中的系统配置内容，如果没有找到则返回默认内容
     */
    public String queryConfigContent(SysConfigEnum sysConfigEnum) {
        String content = queryConfigContent(sysConfigEnum.getIdentification());
        if (StrUtil.isNotBlank(content)) {
            return content;
        } else {
            return sysConfigEnum.getDefaultContent();
        }
    }

    /**
     * 根据标识查询配置类的对象
     * 该方法用于从配置内容中解析出指定类型的配置类对象
     * 如果找到了对应的配置内容，则将其转换为指定的Java对象类型返回；否则返回null
     *
     * @param <T> 配置类的类型，由调用者指定
     * @param flag 配置的唯一标识，用于查询特定的配置内容
     * @param clazz 配置类的Class对象，用于指定要转换的目标类型
     * @return 返回转换后的配置对象，如果找不到或转换失败则返回null
     */
    public <T> T queryConfigClass(String flag, Class<T> clazz) {
        String content = queryConfigContent(flag);
        if (StringUtils.isNotBlank(content)) {
            return JSONUtil.toBean(content, clazz);
        }
        return null;
    }

    /**
     * 根据标识查询配置类的对象
     * 该方法用于从配置内容中解析出指定类型的配置类对象
     * 如果找到了对应的配置内容，则将其转换为指定的Java对象类型返回；否则返回null
     *
     * @param <T> 配置类的类型，由调用者指定
     * @param flag 配置的唯一标识，用于查询特定的配置内容
     * @param clazz 配置类的Class对象，用于指定要转换的目标类型
     * @return 返回转换后的配置对象，如果找不到或转换失败则返回null
     */
    public <T> T queryConfigClass(SysConfigEnum flag, Class<T> clazz) {
        String content = queryConfigContent(flag);
        if (StringUtils.isNotBlank(content)) {
            return JSONUtil.toBean(content, clazz);
        }
        return null;
    }

    /**
     * 查询缓存的系统配置信息
     * 首先尝试从Redis缓存中获取系统配置信息如果未找到，则从数据库中查询，并将结果缓存到Redis中
     *
     * @param identification 系统配置的标识符，用于唯一标识一个配置
     * @return 返回系统配置的内容如果找不到对应的配置，则返回空字符串
     */
    public String queryConfigContent(String identification) {
        SysConfig sysConfig = findCacheOne(SysConfig::getIdentification, identification);
        if(sysConfig != null) {
            return sysConfig.getContent();
        }
        return null;
    }
}
